package com.udf.hive.udf.date;

import org.apache.hadoop.hive.ql.exec.UDF;
import org.apache.hadoop.io.Text;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.logging.Logger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 日期格式转换
 * 
 * @作者 Administrator
 * @version [版本号, 2019年12月12日]
 */
public class DateAnalysisUDF extends UDF
{
    /**
     * 支持的日期格式
     */
    private static String[] dateformatArray = null;

    private static final Pattern p = Pattern.compile("([0-9]+)");
    private static Logger logger = Logger.getLogger("DateAnalysisUDF");
    /**
     * 输出日期转换format
     */

    static {
        // 加载日期格式配置
        // ResourceBundle bundle = ResourceBundle.getBundle("udf");
        String dateformat = "yyyy/MM/dd HH:mm:ss.SSS;yyyy/MM/dd HH:mm:ss.SSS XXX;yyyy/MM/dd HH:mm:ss;yyyy/MM/dd HH:mm:ss XXX;yyyyMMddHHmmss;yyyy/MM/dd;yyyy-MM-dd;yyyy-MM-dd HH:mm:ss;yyyy-MM-dd HH:mm:ss XXX;yyyyMMdd;MM/dd/yyyy;MM/dd/yyyy HH:mm:ss;MM-dd-yyyy;MM-dd-yyyy HH:mm:ss;MM/dd/yy;MM-dd-yy;dd/MM/yyyy;dd-MM-yyyy;yyyy-MM-dd'T'HH:mm:ss.SSSXXX;yyyy-MM-dd HH:mm:ss.SSS";
        dateformatArray = dateformat.split(";");
    }

    /**
     * 输入日期格式
     */
    private static final ThreadLocal<List<SimpleDateFormat>> inputDateFormatThreadLocal = new ThreadLocal<List<SimpleDateFormat>>()
    {
        @Override
        protected List<SimpleDateFormat> initialValue() {
            List<SimpleDateFormat> inputDateFormatList = new ArrayList<>();
            // 日期时间
            for (String dateformat : dateformatArray) {
                inputDateFormatList.add(new SimpleDateFormat(dateformat));
            }
            return inputDateFormatList;
        }
    };

    /**
     * 输出日期格式
     */
    private static final ThreadLocal<SimpleDateFormat> outputDateFormatThreadLocal = new ThreadLocal<SimpleDateFormat>()
    {
        @Override
        protected SimpleDateFormat initialValue() {
            return new SimpleDateFormat("yyyy/MM/dd HH:mm:ss.SSS");
        }
    };

    /**
     * 数据处理逻辑
     * 
     * @param str
     * @return
     */
    public Text evaluate(Text str, Text str2, Text outPutFormat) {
        if (str == null) {
            return null;
        }
        String format = null;
        Date date = null;
        String value = String.valueOf(str).trim();
        SimpleDateFormat outputdate = new SimpleDateFormat();
        if (outPutFormat == null) {
            outputdate = outputDateFormatThreadLocal.get();
        }
        else {
            outputdate = new SimpleDateFormat(outPutFormat.toString());
        }
        List<SimpleDateFormat> inputDateFormatList = new ArrayList<SimpleDateFormat>();
        if (str2 == null) {
            // 开始处理数据
            inputDateFormatList = inputDateFormatThreadLocal.get();

        }
        else {
            String[] formatArray = String.valueOf(str2).split(",");
            for (String dateformat : formatArray) {
                inputDateFormatList.add(new SimpleDateFormat(dateformat));
            }
        }
        for (SimpleDateFormat inputdate : inputDateFormatList) {
            try {
                date = inputdate.parse(value);
                format = outputdate.format(date);
            }
            catch (ParseException e) {
                org.apache.log4j.Logger.getLogger(this.getClass().getName()).error(e);
            }
            if (format != null) {
                // 需要转回去在比对下，防止误匹配，例如2019-12-12
                // 12:12:12能被yyyyMMddHHmmss解析的问题
                String validateStr = inputdate.format(date);
                if (value.equals(validateStr)) {
                    break;
                }
                else {
                    // 如果长度变长了再深度比较一下
                    if (value.length() < validateStr.length() && getDateCompare(value, validateStr)) {
                        break;
                    }
                    else {
                        format = null;
                        date = null;
                    }
                }
            }
        }
        // }
        // else {
        // SimpleDateFormat inputdate = new SimpleDateFormat(str2.toString());
        // try {
        // date = inputdate.parse(value);
        // format = outputdate.format(date);
        // }
        // catch (ParseException e) {
        // e.printStackTrace();
        // }
        // }

        // 返回数据
        if (format != null) {
            return new Text(format);
        }
        else {
            return null;
        }
    }

    public static void main(String[] args) throws ParseException {
        logger.info(String.valueOf(new DateAnalysisUDF().evaluate(new Text("01-01-2001"), new Text("dd-MM-yyyy"),
                new Text("yyyy-MM-dd"))));
    }

    /**
     * 日期格式校验
     * 
     * @param str
     * @param str2
     * @return
     */
    private boolean getDateCompare(String str, String str2) {
        List<String> result1 = new ArrayList<String>();
        List<String> result2 = new ArrayList<String>();
        Matcher m1 = p.matcher(str);
        Matcher m2 = p.matcher(str2);
        while (m1.find()) {
            result1.add(m1.group(0));
        }
        while (m2.find()) {
            result2.add(m2.group(0));
        }
        if (result1.size() != result2.size()) {
            return false;
        }
        else {
            for (int i = 0; i < result1.size(); i++) {
                int i1 = Integer.parseInt(result1.get(i));
                int i2 = Integer.parseInt(result2.get(i));
                if (i1 != i2) {
                    return false;
                }
            }
        }
        return true;
    }
}
